/*
 * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.pig4cloud.pig.ads.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.ads.pig.mapper.AdPlanTempMapper;
import com.pig4cloud.pig.ads.runner.SynAdCreativeWorker;
import com.pig4cloud.pig.ads.runner.SynAdPlanWorker;
import com.pig4cloud.pig.ads.service.*;
import com.pig4cloud.pig.ads.utils.DateUtils;
import com.pig4cloud.pig.ads.utils.RedisLock;
import com.pig4cloud.pig.api.dto.*;
import com.pig4cloud.pig.api.entity.*;
import com.pig4cloud.pig.api.enums.AudiencePackLandTypeEnum;
import com.pig4cloud.pig.api.enums.StatusEnum;
import com.pig4cloud.pig.api.enums.TtConvertTargetEnum;
import com.pig4cloud.pig.api.util.Constants;
import com.pig4cloud.pig.api.util.NoRepeatSubmit;
import com.pig4cloud.pig.api.vo.*;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.enums.PlatformTypeEnum;
import com.pig4cloud.pig.common.core.util.ECollectionUtil;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author hma
 * @ 广告计划管理模块 前端控制器
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/plan")
@Api(value = "plan", tags = "广告计划管理模块")
public class AdvPlanController {
	private static Logger logger = LoggerFactory.getLogger(AdvPlanController.class);
	@Resource
	private AdvPlanService advPlanService;

	@Resource
	private AdPromotionService adPromotionService;

	@Resource
	private AdvCampaignService advCampaignService;

	@Resource
	private AdPlanTempMapper adPlanTempMapper;

	@Resource
	private AdvService advService;

	private final TtPlanCostWarningService ttPlanCostWarningService;

	private final StringRedisTemplate stringRedisTemplate;

	private final AdAssetsService adAssetsService;

	private final AdvCreativeService advCreativeService;

	private final AdvCreativeServiceDetailService advCreativeServiceDetailService;

	private final TaskExecutor taskExecutor;

	private final AdAssetsTrackService adAssetsTrackService;

	private final RedisLock redisLock;




	/**
	 * 分页查询广告计划信息
	 *
	 * @param campaignDto 分页对象
	 * @return 分页对象
	 */
	@SysLog("分页查询广告计划信息")
	@RequestMapping("/getAdvPlanStatisticPage")
	public R getAdvPlanStatisticPage(@RequestBody CampaignDto campaignDto) {
		logger.info("getAdvPlanStatisticPage param:" + JSONObject.toJSON(campaignDto));
		return advPlanService.getAdvPlanStatistic(campaignDto);
	}

	/**
	 * 通过广告计划ID查询广告计划操作状态
	 *
	 * @param adIds
	 * @return
	 */
	@SysLog("getPlanOptStatus")
	@GetMapping("/getPlanOptStatus")
	public R getPlanOptStatus(@RequestParam String adIds) {
		Set<Long> adIdSet = ECollectionUtil.stringToLongSet(adIds);
		if (adIdSet.isEmpty()) {
			return R.ok(Collections.emptyList());
		}
		List<AdPlan> list=new ArrayList<>();
		List<AdPlan> adPlanlist = advPlanService.list(Wrappers.<AdPlan>lambdaQuery().select(AdPlan::getAdId, AdPlan::getOptStatus).in(AdPlan::getAdId, adIdSet));
		List<AdPromotion> adPromotionlist = adPromotionService.list(Wrappers.<AdPromotion>lambdaQuery().select(AdPromotion::getPromotionId, AdPromotion::getOptStatus).in(AdPromotion::getPromotionId, adIdSet));
		list.addAll(adPlanlist);
		adPromotionlist.forEach(adPromotion -> {
			AdPlan adPlan= new AdPlan();
			adPlan.setAdId(adPromotion.getPromotionId());
			adPlan.setOptStatus(adPromotion.getOptStatus());
			list.add(adPlan);
		});
		return R.ok(list);
	}

	/**
	 * 修改广告计划状态
	 *
	 * @param planDto 修改广告计划状态
	 * @return
	 */
	@SysLog("updatePlanStatus")
	@RequestMapping("/updatePlanStatus")
	public R updatePlanStatus(AdvertiserDto planDto) {


		R r = advPlanService.updatePlanStatus(planDto);
		if (r.getCode() == 0) {
			if ("Y".equals(planDto.getIgnoreWarning())) {
				stringRedisTemplate.opsForValue().set(Constants.TT_REDIS_ADID_COST_WARNING_KEY_PRIX_ + planDto.getAdId(), "N");
				AdvertisingWarningVO vo = new AdvertisingWarningVO();
				vo.setAdvertiserId(String.valueOf(planDto.getAdvertiserId()));
				vo.setPlanCostWarning(null);
				return this.submitWarning(vo);
			}
			return r;
		} else {
			return r;
		}
	}


	/**
	 * ----------测试创建广告计划接口-------------------------
	 * 查询用户广告计划上次新建数据
	 *
	 * @param adPlanTempDto 查询对象
	 * @return
	 */
	@SysLog("createAdvPlan")
	@RequestMapping("/createAdvPlan")
	public R createAdvPlan(AdPlanTempDto adPlanTempDto) {
		AdPlanTempDto adPlanTemp = new AdPlanTempDto();
		adPlanTemp.setId(adPlanTempDto.getId());
		List<AdPlanTempVo> adPlanTempVoList = adPlanTempMapper.getUserPlanTemp(adPlanTempDto);
		AdPlanTempVo adPlanTempVo = adPlanTempVoList.get(0);
		AdPlanCreateDto adPlanCreateDto = new AdPlanCreateDto();
		BeanUtils.copyProperties(adPlanTempVo, adPlanCreateDto);
		adPlanCreateDto.setAdvertiserId(adPlanTempDto.getAdvertiserId());
		adPlanCreateDto.setOperation("disable");
//		adPlanCreateDto.setCampaignId(1683702206420055L);
		if (StringUtils.isNotBlank(adPlanTempDto.getAdName())) {
			adPlanCreateDto.setAdName(adPlanTempDto.getAdName());
		} else {
			adPlanCreateDto.setAdName("广告计划名称测试");
		}

		adPlanCreateDto = advPlanService.createAdvPlan(adPlanCreateDto);
		return R.ok(adPlanCreateDto);
	}


	/**
	 * 查询用户广告计划上次新建数据
	 *
	 * @param adPlanTempDto 查询对象
	 * @return
	 */
	@SysLog("getAdvPlan")
	@RequestMapping("/getAdvPlan")
	public R getAdvPlan(AdPlanTempDto adPlanTempDto) {
		advPlanService.getAdPlan(adPlanTempDto.getAdvertiserId().toString(), adPlanTempDto.getAds());
		return R.ok();
	}


	@RequestMapping("/getByAdvertiserIds")
	public R getByAdvertiserIds(AdPlanTempDto adPlanTempDto) {
		List<AdPlan> byAdvertiserId = advPlanService.getByAdvertiserIds(adPlanTempDto);
		List<AdPlanSearch> result = Lists.newArrayList();
		if (CollectionUtils.isNotEmpty(byAdvertiserId)) {
			byAdvertiserId.forEach(adPlan -> {
				result.add(new AdPlanSearch(adPlan.getAdId().toString(),adPlan.getAdName()));
			});
		}
		return R.ok(result);
	}


	@PostMapping("/getByAdids")
	public R getByAdids(@RequestBody String adids) {
		if (StringUtils.isBlank(adids)) {
			return R.failed("广告ID为空");
		}
		List<AdPlan> adPlans = advPlanService.getByAdids(adids);
		return R.ok(adPlans);
	}

	/**
	 * 根据计划ID获取计划信息
	 * @param adPlanTempDto
	 * @return
	 */
	@PostMapping("/getAdPlan")
	public R getAdPlan(@RequestBody AdPlanTempDto adPlanTempDto){
		Map<String,Object> resultMap = new HashMap<>();
		AdPlan adPlan = advPlanService.getById(adPlanTempDto.getAdId());
		if (Objects.nonNull(adPlan)){
			//获取应用ID
			// 资产ID集合，计划正式表为[111,222]
			List<Long> assetIdList = JSON.parseArray(adPlan.getAssetIds(),Long.class);
			if (CollectionUtils.isEmpty(assetIdList)){
				return R.failed("事件管理模式下不能复制非事件管理的广告计划");
			}

			AdAssets adAssets = adAssetsService.getOne(Wrappers.<AdAssets>lambdaQuery()
					.eq(AdAssets::getDeleted,0)
					.eq(AdAssets::getAdvertiserId,adPlan.getAdvertiserId())
					.eq(AdAssets::getAssetId,assetIdList.get(0)));
			if (adAssets != null) {
				resultMap.put("appCloudId",adAssets.getAppCloudId());
			}
			resultMap.put("externalAction",adPlan.getExternalAction());
			resultMap.put("deepExternalAction",adPlan.getDeepExternalAction());
			resultMap.put("externalActionName", TtConvertTargetEnum.getName(adPlan.getExternalAction()));
			resultMap.put("deepExternalActionName",StringUtils.isBlank(TtConvertTargetEnum.getName(adPlan.getDeepExternalAction())) ? "无" : TtConvertTargetEnum.getName(adPlan.getDeepExternalAction()));
		}
		return R.ok(resultMap);
	}

	@PostMapping("/getGdtByAdids")
	public R getGdtByAdids(@RequestBody String adids) {
		if (StringUtils.isBlank(adids)) {
			return R.failed("广告ID为空");
		}
		List<PlanGdtAttrAnalyseReportVo> adPlans = advPlanService.getGdtByAdids(adids);
		return R.ok(adPlans);
	}

	/**
	 * 修改广告预算（定时修改）
	 *
	 * @param budgetDto
	 * @return
	 */
	@RequestMapping("/updatePlanBudget")
	@SysLog("updatePlanBudget")
	public R updatePlanBudget(BudgetDto budgetDto) {
		if (null == budgetDto) {
			return R.failed("param is empty");
		}
		String advertiserId = budgetDto.getAdvertiserId();
		if (StringUtils.isBlank(advertiserId)) {
			return R.failed("advertiserId is empty");
		}
		if (null == budgetDto.getAdId()) {
			return R.failed("adId is empty");
		}
		if (null == budgetDto.getVersionType()) {
			return R.failed("versionType is empty");
		}
		if (null == budgetDto.getType()) {
			budgetDto.setType(StatusEnum.TYPE_ONE.getStatus());
		}
		return advPlanService.updatePlanBudget(budgetDto);
	}


	/**
	 * 修改广告出价
	 *
	 * @param budgetDto
	 * @return
	 */
	@RequestMapping("/updatePlanCpaBid")
	@SysLog("updatePlanCpaBid")
	public R updatePlanCpaBid(BudgetDto budgetDto) {
		if (null == budgetDto) {
			return R.failed("param is empty");
		}
		String advertiserId = budgetDto.getAdvertiserId();
		if (StringUtils.isBlank(advertiserId)) {
			return R.failed("advertiserId is empty");
		}
		if (null == budgetDto.getAdId()) {
			return R.failed("adId is empty");
		}
		if (null == budgetDto.getCpaBid()) {
			return R.failed("cpaBid  is empty");
		}
		if (null == budgetDto.getVersionType()) {
			return R.failed("versionType  is empty");
		}
		return advPlanService.updatePlanCpaBid(budgetDto);
	}

	/**
	 * 查询广告计划预约当天定时设置预算值
	 *
	 * @param adId
	 * @return success/false
	 */
	@SysLog("查询该账户设置的日预算")
	@RequestMapping("/getPlanBudget")
	public R getPlanBudget(Long adId) {
		return advService.getAdvertiserJobBudget(null, null, adId, StatusEnum.OPERATE_THREE.getStatus());
	}


	/**
	 * @zhuxm
	 * @获取广告组账号预警阈值
	 */
	@SysLog("获取广告组账号预警阈值")
	@RequestMapping("/getWarning")
	public R getWarning(String advertiserId) {
		if (StringUtils.isBlank(advertiserId)) {
			return R.failed("广告账号不允许为空");
		}
		List<String> adList = advService.getOwnerAdv(SecurityUtils.getUser().getId(), PlatformTypeEnum.TT.getValue());
		if (adList == null || adList.size() == 0 || !adList.contains(advertiserId)) {
			return R.failed("请选择属于自己的账号");
		}

		return R.ok(ttPlanCostWarningService.getById(advertiserId));
	}


	/**
	 * @zhuxm
	 * @获取广告组账号预警阈值
	 */
	@SysLog("提交推广计划预警阈值")
	@RequestMapping("/submitWarning")
	public R submitWarning(@Valid AdvertisingWarningVO vo) {

		if (vo == null) {
			return R.failed("参数不能为空");
		}

		if (StringUtils.isBlank(vo.getAdvertiserId())) {
			return R.failed("广告账号不允许为空");
		}


		TtPlanCostWarning entity = new TtPlanCostWarning();
		entity.setPlanCostWarning(vo.getPlanCostWarning());
		entity.setAdvertiserId(vo.getAdvertiserId());
//		目前此版本不支持
//		UpdateWrapper<TtPlanCostWarning> updateWrapper = new UpdateWrapper<>();
//		updateWrapper.eq("advertiser_id", entity.getAdvertiserId()).set("plan_cost_warning", entity.getPlanCostWarning());
//
//		return  R.ok(ttPlanCostWarningService.saveOrUpdate(entity, updateWrapper));
		return R.ok(ttPlanCostWarningService.saveOrUpdate(entity));
	}

	/**
	 * @zhuxm
	 * @头条广告计划复制
	 */
	@NoRepeatSubmit(lockTime = 3000)
	@SysLog("头条广告计划复制")
	@RequestMapping("/copyIt")
	public R copyIt(@Valid AdPlanCopyDTO dto) {
		try {
			AdPlan adPlan = advPlanService.getById(dto.getAdId());
			if (adPlan == null) {
				return R.failed("当前广告计划不存在");
			}
			// 新营销链路的校验
			Long campaignId = adPlan.getCampaignId();
			AdCampaign adCampaign = advCampaignService.getOne(Wrappers.<AdCampaign>lambdaQuery().eq(AdCampaign::getCampaignId,campaignId));
			if (adCampaign != null && "UNLIMITED".equals(adCampaign.getMarketingPurpose())) {
				return R.failed("营销链路模式下不能复制非营销链路的广告计划");
			}
			//获取资产字符串 复制时从正式表(存储的是JSON类型的字符串带[])
			String assetIds = this.convertArrayToStr(adPlan.getAssetIds());
			if (StringUtils.isBlank(assetIds)) {
				return R.failed("事件管理模式下不能复制非事件管理的广告计划");
			}

			//获取监测组信息
			AdAssetsTrack assetsTrack = adAssetsTrackService.getOne(Wrappers.<AdAssetsTrack>lambdaQuery()
					.eq(AdAssetsTrack::getDeleted, 0)
					.eq(AdAssetsTrack::getMediaCode,1)
					.eq(AdAssetsTrack::getAdvertiserId,dto.getAdvertiserId())
					.eq(AdAssetsTrack::getTrackUrlGroupId, dto.getTrackUrlGroupId()));
			if (assetsTrack == null) {
				return R.failed("转化信息不存在，请稍后再试。");
			}

			//校验目标广告账户是否有复制计划转化目标和深度转化目标
			R check = this.checkExternalAction(dto,assetsTrack);
			if (check.getCode() == CommonConstants.FAIL) {
				return check;
			}

			String webUrl = dto.getWebUrl();
			String downloadType = adPlan.getDownloadType();

			//原有广告计划的广告账户
			String sourceAdvertiserId = adPlan.getAdvertiserId();

			//避免不是最新数据，重新拉取一下
			advCreativeServiceDetailService.saveAdCreativeDetailList(sourceAdvertiserId, Long.valueOf(dto.getAdId()));

			//查询复制的广告创意信息
			TtCreativeDetail ttCreativeDetail = advCreativeServiceDetailService.getOne(Wrappers.<TtCreativeDetail>query().lambda()
					.eq(TtCreativeDetail::getAdvertiserId, sourceAdvertiserId).eq(TtCreativeDetail::getAdId, dto.getAdId()), false);
			if (ttCreativeDetail == null) {
				return R.failed("复制的广告创意明细不存在，请稍后再试。");
			}

			AdPlanCreateDto adDto = this.buildPlanDto(adPlan,dto,assetsTrack);

			log.info("复制广告计划参数========>{}", JSON.toJSONString(adDto));
			//创建推广计划
			AdPlanCreateDto cpSuccessVo = advPlanService.createAdvPlan(adDto);
			if (cpSuccessVo == null || cpSuccessVo.getAdId() == null) {
				log.error("广告计划复制失败");
				return R.failed("广告计划复制失败");
			}
			// 拉取第三方广告计划
			SynAdPlanWorker synAdPlanWorker = new SynAdPlanWorker(advPlanService, String.valueOf(dto.getAdvertiserId()), cpSuccessVo.getAdId());
			taskExecutor.execute(synAdPlanWorker);

			//创建推广创意
			ttCreativeDetail.setAdId(String.valueOf(cpSuccessVo.getAdId()));
			ttCreativeDetail.setAdvertiserId(String.valueOf(dto.getAdvertiserId()));

			//当广告计划的投放范围为穿山甲时,
			//video_play_effective_track_url视频有效播放（监测链接），投放范围为穿山甲时暂不支持设置此链接
			//video_play_done_track_url视频播完（监测链接），投放范围为穿山甲时暂不支持设置此链接
			//video_play_track_url视频播放（监测链接），投放范围为穿山甲时暂不支持设置此链接
			String deliveryRange = adDto.getDeliveryRange();
			if ("UNION".equals(deliveryRange)) {
				ttCreativeDetail.setVideoPlayEffectiveTrackUrl(null);
				ttCreativeDetail.setVideoPlayDoneTrackUrl(null);
				ttCreativeDetail.setVideoPlayTrackUrl(null);
			}
			//下载链接时设置新的应用下载详情页
			if ("DOWNLOAD_URL".equals(downloadType)) {
				ttCreativeDetail.setWebUrl(webUrl);
			}
			//创建广告创意
			ttCreativeDetail.setAppName(assetsTrack.getAppName());
			//创意明细表存储的创意标签是JSON格式  ad_keywords 转为逗号分割
			this.strJoining(ttCreativeDetail);
			TtAdCreativeResponseNew response = advCreativeService.copyAdvCreative(ttCreativeDetail);
			if (CollectionUtils.isNotEmpty(response.getErrors())) {
				//创意失败
				List<String> msgList = response.getErrors().stream().filter(Objects::nonNull).distinct().map(TtCreativeErrorResult::getMessage).collect(Collectors.toList());
				return R.failed("创意复制失败: "+JSON.toJSONString(msgList));
			}

			// 拉取第三方广告创意
			SynAdCreativeWorker synAdCreativeWorker =
					new SynAdCreativeWorker(advCreativeService, advCreativeServiceDetailService, String.valueOf(dto.getAdvertiserId()), cpSuccessVo.getAdId());
			taskExecutor.execute(synAdCreativeWorker);

			return R.ok((cpSuccessVo == null || cpSuccessVo.getAdId() == null) ? "" : cpSuccessVo.getAdId(), "广告计划复制成功！");
		} catch (Exception e) {
			log.error("广告计划复制失败", e);
			return R.failed(StringUtils.isBlank(e.getMessage()) ? "广告计划复制失败" : e.getMessage());
		}
	}

	/**
	 * [123,234] ==> "123,234"
	 * @param sourceStr
	 * @return
	 */
	private String convertArrayToStr(String sourceStr) {
		return Arrays.stream(JSON.parseObject(sourceStr,String[].class)).collect(Collectors.joining(","));
	}

	private R checkExternalAction(AdPlanCopyDTO dto,AdAssetsTrack assetsTrack) {
		AdAssetsTrackReq trackReq = new AdAssetsTrackReq();
		trackReq.setAdvertiserId(dto.getAdvertiserId());
		trackReq.setAppCloudId(String.valueOf(assetsTrack.getAppCloudId()));
		R track = adAssetsTrackService.getOptimizedGoal(trackReq);
		if (track.getCode() == CommonConstants.FAIL) {
			return track;
		} else {
			JSONObject data = (JSONObject) track.getData();
			JSONArray goals = data.getJSONArray("goals");
			if (CollectionUtils.isEmpty(goals)) {
				return R.failed("资产下没有事件，请先创建事件");
			}
			//校验转化目标\深度转化目标
			boolean externalActionFlag = false;
			boolean deepExternalActionFlag = false;
			for (int j = 0; j < goals.size(); j++) {
				JSONObject goals_obj = goals.getJSONObject(j);
				//支持的转化目标
				String externalAction = goals_obj.getString("external_action");
				if (externalAction.equals(dto.getExternalAction())) {
					externalActionFlag = true;
					if (StringUtils.isNotBlank(dto.getDeepExternalAction())
							&& !"DEEP_BID_DEFAULT".equals(dto.getDeepExternalAction())) {
						JSONArray deepGoals = goals_obj.getJSONArray("deep_goals");
						for (int k = 0; k < deepGoals.size(); k++) {
							JSONObject deep_goals_obj = deepGoals.getJSONObject(k);
							//支持的深度转化目标
							String deepExternalAction = deep_goals_obj.getString("deep_external_action");
							if (deepExternalAction.equals(dto.getDeepExternalAction())) {
								deepExternalActionFlag = true;
								break;
							}
						}
					}
					break;
				}
			}
			if (!externalActionFlag) {
				return R.failed("广告账户"+dto.getAdvertiserId()+",不支持转化目标:"+TtConvertTargetEnum.getName(dto.getExternalAction())+"("+dto.getExternalAction()+"),请先创建");
			}
			if (!deepExternalActionFlag && StringUtils.isNotBlank(dto.getDeepExternalAction())
					&& !"DEEP_BID_DEFAULT".equals(dto.getDeepExternalAction())) {
				return R.failed("广告账户"+dto.getAdvertiserId()+",不支持深度转化目标:"+TtConvertTargetEnum.getName(dto.getDeepExternalAction())+"("+dto.getDeepExternalAction()+"),请先创建");
			}
		}

		return R.ok();
	}

	private AdPlanCreateDto buildPlanDto(AdPlan adPlan,AdPlanCopyDTO dto,AdAssetsTrack assetsTrack) {
		//组装新的推广计划
		AdPlanCreateDto adDto = new AdPlanCreateDto();
		BeanUtils.copyProperties(adPlan, adDto);
		//监测链接信息
		// 不能使用原计划的资产
//		adDto.setAssetIds(this.convertArrayToStr(adPlan.getAssetIds()));
		adDto.setAssetIds(String.valueOf(assetsTrack.getAssetId()));
		//转化目前属性不一致，需要重新set
		adDto.setConvertType(dto.getExternalAction());
		adDto.setDeepExternalAction(dto.getDeepExternalAction());
		adDto.setTrackGroupId(Long.valueOf(dto.getTrackUrlGroupId()));
		adDto.setTrackGroupType("TRACK_URL_GROUP_ID");

		//用户发生行为天数类型不对复制失败，当interest_action_mode传CUSTOM时有效
		if (adPlan.getActionDays() != null) {
			adDto.setActionDays(adPlan.getActionDays().toString());
		}

		//设置投放时间
		Date now = new Date();
		String endTime = adPlan.getEndTime();
		String startTime = adPlan.getStartTime();
		if (StringUtils.isNotBlank(endTime) && DateUtils.isValidDate(endTime, "yyyy-MM-dd HH:mm")
				&& StringUtils.isNotBlank(startTime) && DateUtils.isValidDate(startTime, "yyyy-MM-dd HH:mm")) {
			Long days = DateUtils.getDaySub(startTime, endTime);
			endTime = DateUtils.dateToString(DateUtils.addDays(now, days.intValue()), "yyyy-MM-dd HH:mm");
		}
		adDto.setStartTime(DateUtils.dateToString(now, "yyyy-MM-dd HH:mm"));
		adDto.setEndTime(endTime);

		//新的广告账户
		adDto.setAdvertiserId(Long.valueOf(dto.getAdvertiserId()));
		//新的广告计划名称
		adDto.setAdName(dto.getAdName());
		//新的广告组
		adDto.setCampaignId(Long.valueOf(dto.getCampaignId()));
		adDto.setDownloadUrl(assetsTrack.getDownloadUrl());
		//v2.4.2设置目标转化的监测链接
//			adDto.setActionTrackUrl(convertTrack.getActionTrackUrl());
		//BeanUtils.copyProperties(adPlan, adDto); 会复制带[]的监测链接，会导致 action_track_url.0: Not a valid URL
		adDto.setActionTrackUrl(null);
		adDto.setDownPackage(assetsTrack.getPackageName());
		adDto.setAppType(AudiencePackLandTypeEnum.APP_ANDROID.getType());

//		adDto.setDeepBidType(adPlan.getDeepBidType());
		adDto.setDeepBidType("BID_FIRST_ACTION".equals(adPlan.getDeepBidType()) ? null : adPlan.getDeepBidType());
		adDto.setDeepCpabid(adPlan.getDeepCpabid());
		adDto.setRoiGoal(adPlan.getRoiGoal());
		//创建广告inventory_type、action_track_url 需要的是逗号分割,而复制时从正式表(存储的是JSON类型的字符串带[])
		//已经在创建是处理了
		//adDto.setInventoryType(Arrays.stream(JSON.parseObject(adDto.getInventoryType(),String[].class)).collect(Collectors.joining(",")));
		//设置落地页
		if ("EXTERNAL_URL".equals(adPlan.getDownloadType())) {
			adDto.setExternalUrl(dto.getWebUrl());
		}
		String operation = "enable";
		adDto.setOperation(operation);
		adDto.setCopyFlag(true);

		return adDto;

	}

	/**
	 * ["111","222"]  ==>  111,222
	 * @param ttCreativeDetail
	 */
	private void strJoining(TtCreativeDetail ttCreativeDetail) {
		// 创意标签已经改为非必填了
		if (StringUtils.isNotBlank(ttCreativeDetail.getAdKeywords())) {
			JSONArray adKeywords= JSON.parseArray(ttCreativeDetail.getAdKeywords());
			String[] value = adKeywords.toArray(new String[adKeywords.size()]);
			ttCreativeDetail.setAdKeywords(Arrays.stream(value).collect(Collectors.joining(",")));
		}
	}

	private String getClientId() {
		return UUID.randomUUID().toString();
	}

}
